<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>利用Jcrop+Canvas实现前端图片裁剪</title>
	<link rel="stylesheet" href="jquery.Jcrop.min.css">
	<script type="text/javascript" src="../../../assets/js/jquery-1.7.2.min.js"></script>
	<script src="jquery.Jcrop.min.js"></script>
</head>
<body>
	<button id="upload">上传图片</button>
<script>
	$(function(){

		function crop(node, src, w, w2, rX, rY, callBack){
			/*
			 node: 节点id名(在该节点后添加图片操作区)
			 src:  上传后的图片地址
			 w:    图片操作区宽度(number)
			 w2:   预览框宽度(number)
			 rX:   裁剪比例x轴(number)
			 rY:   裁剪比例y轴(number)
			 */

			var _node = $('#'+node+''),
				_cropBox = $('#'+node+'_cropBox');

			if(_cropBox) _cropBox.remove();

			var html = '<div id="'+node+'_cropBox"><div id="'+node+'_cutBox"><span id="'+node+'_vamSpan"></span><img id="'+node+'_cutBoxImg" src="'+src+'"></div><div id="'+node+'_preview"><img id="'+node+'_preViewImg" src="'+src+'"></div><canvas id="'+node+'_canvas"></canvas><div style="clear: both;"><button id="'+node+'_submit">确认截取</button></div></div>';

			_node.after(html);

			var _cutBox      = $('#'+node+'_cutBox'),
				_vamSpan     = $('#'+node+'_vamSpan'),
				_cutBoxImg   = $('#'+node+'_cutBoxImg'),
				_preview     = $('#'+node+'_preview'),
				_preViewImg  = $('#'+node+'_preViewImg'),
				_canvas      = $('#'+node+'_canvas'),
				_submit      = $('#'+node+'_submit');

			var h  = Math.round(w*rY/rX),
				h2 = Math.round(w2*rY/rX);

			_cutBox.css({'width': w+'px', 'height': h+'px', 'backgroundColor': '#ccc', 'float': 'left', 'overflow': 'hidden', 'fontSize': 0, 'lineHeight': 'normal', 'textAlign': 'center'});
			_vamSpan.css({'width': '1px', 'height': '100%', 'marginLeft': '-1px'});
			_cutBoxImg.css({'verticalAlign': 'middle'});
			_preview.css({'width': w2+'px', 'height':  h2+'px', 'float': 'left', 'margin': '10px 0 0 10px', 'overflow': 'hidden', 'boxShadow': '0 0 5px 3px #d0d0d0'});
			_canvas.css({'margin': '10px 0 0 10px', 'display': 'none', 'visibility': 'hidden'});
			_submit.css({'marginTop': '10px'});

			var jcrop_api,
				boundx,
				boundy,
				result,
				cut;

			function updatePreview(c){
				if (parseInt(c.w) > 0){
					var rx = w2 / c.w;
					var ry = h2 / c.h;

					_preViewImg.css({
						width: Math.round(rx * boundx) + 'px',
						height: Math.round(ry * boundy) + 'px',
						marginLeft: '-' + Math.round(rx * c.x) + 'px',
						marginTop: '-' + Math.round(ry * c.y) + 'px'
					});

					cut = c;
				}
			}

			_cutBoxImg.Jcrop({
				onChange: updatePreview,
				onSelect: updatePreview,
				bgColor: 'transparent',
				boxWidth: w,
				boxHeight: h,
				aspectRatio: rX/rY
			}, function(){
				_cutBox.children('div,span').css({'display': 'inline-block', 'verticalAlign': 'middle'});

				jcrop_api = this;

				var bounds = this.getBounds(),
					p = {};

				boundx = bounds[0];
				boundy = bounds[1];

				if( boundx/w2 - boundy/h2 >= 0 ){
					p.y = 0;
					p.h = Math.round(boundy);
					p.w = Math.round(p.h/h2*w2);
					p.x = Math.round((boundx-p.w)/2);
				}else{
					p.x = 0;
					p.w = Math.round(boundx);
					p.h = Math.round(p.w/w2*h2);
					p.y = Math.round((boundy-p.h)/2);
				}
				this.animateTo([p.x, p.y, p.w, p.h]);
			});

			_submit.on('click', function(){
				var img = document.getElementById(''+node+'_cutBoxImg');
				var canvas = document.getElementById(''+node+'_canvas');
				var ctx = canvas.getContext("2d");

                _canvas.attr({'width': Math.round(cut.w), 'height': Math.round(cut.h)});

				//context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);  剪切图像，并在画布上定位被剪切的部分
				ctx.drawImage(img, Math.round(cut.x), Math.round(cut.y), Math.round(cut.w), Math.round(cut.h), 0, 0, Math.round(cut.w), Math.round(cut.h));
				result = canvas.toDataURL();
				callBack(result);
			});
		}

		$('#upload').click(function(){
			crop('upload', 'img/3.jpg', 600, 300, 79, 37, function(v){
			    alert(v);
			});
		});
	});
</script>
</body>
</html>